"""
@Time : 2023/12/30 20:18
@Auth : Mr.Zhao
#Function : 
"""
# coding:utf8
from smtplib import SMTP_SSL
from email.header import Header
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
import yaml
from common.Logging import logger
from common.all_path import path

class Mail:
    """
        powered by Mr Will
        at 2018-12-22
        用来获取配置并发送邮件
    """

    def __init__(self):
        # 读取配置文件
        f = open(file=path + "lib/conf.yml", mode='r', encoding="utf-8")
        self.mail_info = yaml.safe_load(stream=f)['mail']
        f.close()

        # 发件人
        self.mail_info['from'] = self.mail_info['username']
        # smtp服务器域名，截取域名，然后拼上smtp.
        # print(self.mail_info['username'].__len__())
        # print(len(self.mail_info['username']))
        self.mail_info['hostname'] = 'smtp.' + self.mail_info['username']\
        [self.mail_info['username'].rfind('@') + 1:self.mail_info['username'].__len__()]
        '''服务器域名的截取：
            self.mail_info['username']即username对应的val值
            '\'为连接符，表示和下一行连接
            self.mail_info['username'].rfind('@') + 1 表示最后一个@的后一个位置
            self.mail_info['username'].__len__() 表示整个字符串（self.mail_info['username']）的长度，同 print(len(self.mail_info['username']))
        '''
        logger.debug(self.mail_info)


    def send(self, text):
        # print("Test Zero")
        # 这里使用SMTP_SSL就是默认使用465端口，如果发送失败，可以使用587
        smtp = SMTP_SSL(self.mail_info['hostname'], port = 465)
        # print("Test One")
        smtp.set_debuglevel(0)  #简洁日志，不报错没有日志
        '''
        上述代码的作用是使用SMTP_SSL来建立到SMTP服务器的安全连接，并设置调试级别为0。
        SMTP_SSL是Python smtplib库中的一个类，用于建立到SMTP服务器的安全连接，通常默认使用端口465。
        smtp.set_debuglevel(0) 用于设置调试级别，将调试级别设置为0，这表示不输出调试信息。
        总体而言，这段代码的作用是使用安全的SMTP连接来与指定的SMTP服务器进行通信，并设置调试级别为0，以便在通信过程中不输出调试信息。
        '''

        ''' SMTP 'ehlo' command.
        Hostname to send for this command defaults to the FQDN of the local
        host.
        '''
        smtp.ehlo(self.mail_info['hostname'])
        # 这行代码发送EHLO（扩展问候）命令到邮件服务器，以便与服务器建立连接并进行通信。EHLO命令用于向服务器表明客户端支持的邮件传输扩展。

        # 登录
        smtp.login(self.mail_info['username'], self.mail_info['password'])
        #这行代码用于使用给定的用户名和密码进行登录到SMTP服务器

        # 普通HTML邮件
        # msg = MIMEText(text, 'html', self.mail_info['mail_encoding'])

        # 支持附件的邮件
        # print("Test Two")
        msg = MIMEMultipart() #创建一个多部分的邮件消息对象。
        msg.attach(MIMEText(text, 'html', self.mail_info['mail_encoding'])) #向邮件消息中添加HTML格式的邮件正文，其中text是HTML格式的邮件内容，
        msg['Subject'] = Header(self.mail_info['mail_subject'], self.mail_info['mail_encoding'])#设置邮件的主题，使用self.mail_info['mail_subject']作为主题内容，并指定编码方式。
        # msg['from'] = self.mail_info['from']
        # 添加自定义昵称
        # print("Test Three")
        h = Header(self.mail_info['mailnick'], 'utf-8') # 创建一个自定义昵称的邮件头部，使用self.mail_info['mailnick']作为昵称内容，并指定编码方式为UTF-8。
        h.append('<' + self.mail_info['from'] + '>', 'ascii') #将发件人地址添加到自定义昵称中，并指定编码方式为ASCII。
        #print(f'h = {h}')
        msg["from"] = h #将自定义昵称作为发件人信息添加到邮件消息中

        # logger.debug(self.mail_info)
        # logger.debug(text)
        msg['to'] = ','.join(self.mail_info['to']) #邮件发送人
        msg['cc'] = ','.join(self.mail_info['cc']) #邮件抄送人
        receive = self.mail_info['to'] #创建一个收件人列表 receive，并将 self.mail_info['to'] 的邮件地址添加到其中。
        receive += self.mail_info['cc'] #将抄送人列表 self.mail_info['cc'] 的邮件地址添加到收件人列表 receive 中，以便将所有的收件人和抄送人统一处理

        #添加附件（文件内容，格式，名字）
        for i in range(len(self.mail_info['filepaths'])):
            att1 = MIMEText(open(self.mail_info['filepaths'][i], 'rb').read(), 'base64', 'utf-8') #创建一个MIMEText对象，将以二进制形式读取附件文件内容，并使用base64进行编码
            att1['Content-Type'] = 'application/octet-stream'# 设置附件的内容类型为“application/octet-stream”，表示这是一个二进制流数据。
            # att1['Content-Disposition'] = 'attachment; filename= "'+self.mail_info['filenames'][i]+'"'
            att1.add_header('Content-Disposition', 'attachment', filename=('gbk', '', self.mail_info['filenames'][i])) # 设置附件的Content-Disposition头部，这里使用了gbk编码方式，并指定了附件的文件名

            msg.attach(att1) #将创建的附件对象添加到邮件消息中。

        try:
            smtp.sendmail(self.mail_info['from'], receive, msg.as_string())
            smtp.quit()
            logger.info('邮件发送成功')
        except Exception as e:
            logger.error('邮件发送失败：')
            logger.exception(e)



if __name__ == '__main__':
    mail = Mail()
    print(mail.mail_info)

    #带附件
    # mail.mail_info['filepaths'] = ['F:\\git\\MyTestFrame06\\data\\result-HTTP接口用例-all.xlsx']
    # mail.mail_info['filenames'] = ['result-HTTP接口用例-all.xlsx']
    #mail.send('hello will')

    #带附件
    # mail.mail_info['filepaths'] = [path + 'lib\\verify.png']
    # mail.mail_info['filenames'] = ['验证码图片']
    # mail.send("hello world")

    #带html模板
    mail.mail_info['filepaths'] = [path + 'lib\\verify.png']
    mail.mail_info['filenames'] = ['验证码图片']

    with open(path + 'lib\\module1.html', mode = 'r', encoding='utf8') as f:
        text = f.read()
    mail.send(text)
